package com.gljx.web.controller.back.activiti;

import com.gljx.constant.Constant;
import com.gljx.util.CommonUtil;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.task.Comment;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 历史流程
 * @Author: LiXiang
 * @Date: Created in 2018/2/6 14:17
 */
@Controller
@RequestMapping(value = "/activiti")
public class ImgHistroyController {

    static final Logger logger = Logger.getLogger(ImgHistroyController.class);

    @Resource
    private ProcessEngine processEngine;

    @Resource
    private RepositoryService repositoryService;

    @Resource
    private TaskService taskService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private HistoryService historyService;

    /**
     * 跳转到流程图页面
     * @Author:  LiXiang
     * @Date: Created in 2018/2/6 9:03
     * @param fnumberName 单据名称
     * @param fnumber	  单据编号
     * @return
     * @throws Exception
     */
    @RequestMapping("/openActivitiImagePage.action")
    public ModelAndView openActivitiImagePage(String fnumberName,
                                              String fnumber)
            throws Exception {

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("backManage/activiti/img_history");

        modelAndView.addObject("fnumberName", fnumberName);
        modelAndView.addObject("fnumber", fnumber);

        //查询历史任务列表
        List<HistoricTaskInstance> tasklist =
                historyService
                        .createHistoricTaskInstanceQuery()
                        .processVariableValueEquals(fnumberName,fnumber)
                        //根据执行任务排序
                        .orderByExecutionId().desc()
                        //根据开始时间排序
                        .orderByHistoricTaskInstanceStartTime().desc()
                        .list();
        if(tasklist == null || tasklist.size() <=0)
        {
            //找不到流程
            modelAndView.addObject("message", Constant.messageNoAct);
        }else{

            //将流程实例ID放入
            String pid = tasklist.get(0).getProcessInstanceId();
            modelAndView.addObject("pid", pid);
        }

        return modelAndView;
    }

    /**
     * 获取流程图像，已执行节点和流程线高亮显示
     */
    @RequestMapping("getActivitiProccessImage")
    public void getActivitiProccessImage(String pProcessInstanceId, HttpServletResponse response) throws Exception {

        // 设置页面不缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/png");

        OutputStream os = response.getOutputStream();
        try {
            //  获取历史流程实例
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(pProcessInstanceId).singleResult();

            if (historicProcessInstance == null) {
                //throw new BusinessException("获取流程实例ID[" + pProcessInstanceId + "]对应的历史流程实例失败！");
            } else {
                // 获取流程定义
                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                        .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());

                // 获取流程历史中已执行节点，并按照节点在流程中执行先后顺序排序
                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                        .processInstanceId(pProcessInstanceId).orderByHistoricActivityInstanceId().asc().list();

                // 已执行的节点ID集合
                List<String> executedActivityIdList = new ArrayList<String>();
                int index = 1;

                //获取已经执行的节点
                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
                    executedActivityIdList.add(activityInstance.getActivityId());
                    //高亮节点设置
                    index++;
                }

                // 获取流程图图像字符流
                InputStream imageStream = ProcessDiagramGenerator.generateDiagram(processDefinition, "png", executedActivityIdList);

                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.close();
                imageStream.close();
            }
            //完成-获取流程图图像
        } catch (Exception e) {
            logger.error("【异常】-获取流程图失败！" + e.getMessage());
            e.getStackTrace();
        }
    }

    /**
     * 获取节点信息
     * @Author:  LiXiang
     * @Date: Created in 2018/2/1 11:23
     */
    @RequestMapping("/getHistroyTaskByPid")
    @ResponseBody
    public List<Object> mytest(String fnumberName,String fnumber) throws IllegalAccessException {
        //结果集
        List<Object> results = new ArrayList<>();
        if(StringUtils.isEmpty(fnumber)||StringUtils.isEmpty(fnumberName)){
            return results;
        }
        //流程实例
       /* HistoricProcessInstance hisProcessInstance =
                historyService
                        .createHistoricProcessInstanceQuery()
                        .processInstanceId(pid)
                        .singleResult();*/
        List<HistoricProcessInstance> list = historyService
                .createHistoricProcessInstanceQuery()
                .variableValueEquals(fnumberName,fnumber)
                .orderByProcessInstanceEndTime().asc()
                .list();

        if(list == null || list.size()<=0)
        {
            return results;
        }


        for (HistoricProcessInstance hisProcessInstance:list){
            if(hisProcessInstance == null){
                return results;
            }
            List<HistoricTaskInstance> tasklist =
                    historyService
                            .createHistoricTaskInstanceQuery()
                            .processInstanceId(hisProcessInstance.getId())
                            .orderByHistoricTaskInstanceEndTime().asc()
                            .list();

            //当前流程的
            List<Comment> commentList = taskService.getProcessInstanceComments(hisProcessInstance.getId());





            //将任务信息和批注装载
            for(int i = 0; i < tasklist.size(); i++)
            {

                //历史任务
                HistoricTaskInstance task = tasklist.get(i);

                Map<String,Object> map = new HashMap<String,Object>();

                //任务ID
                map.put("id",task.getId());

                //流程实例ID
                map.put("processInstanceId",task.getProcessInstanceId());

                //任务开始时间
                map.put("startTime",CommonUtil.dateToDate(task.getStartTime()));

                //任务结束时间
                map.put("endTime",CommonUtil.dateToDate(task.getEndTime()));

                //节点名称
                map.put("name",task.getName());

                //节点经办人
                map.put("assignee",task.getAssignee());

                for(int j = 0; j < commentList.size(); j++)
                {
                    //循环的批注
                    Comment comment = commentList.get(j);
                    //当批注的任务ID等于任务的ID时将数据装载
                    if(tasklist.get(i).getId()
                            .equals(commentList.get(j).getTaskId()))
                    {
                        //全部批注
                        map.put("commonFullMessage",comment.getFullMessage());

                        //批注时间
                        map.put("commonTime",CommonUtil.dateToDate(comment.getTime()));

                        //批注人
                        map.put("commonUserName",comment.getUserId());

                    }
                }
                results.add(map);
            }

            Map<String,Object> processInstanceMap = new HashMap<String,Object>();
            processInstanceMap.put("startTime", CommonUtil.dateToDate(hisProcessInstance.getStartTime()));
            processInstanceMap.put("endTime",CommonUtil.dateToDate(hisProcessInstance.getEndTime()));
            processInstanceMap.put("startUserId",hisProcessInstance.getStartUserId());
            results.add(processInstanceMap);
        }

        return results;
    }
}
